/*
 * C/C++ Lessons Program
 * 
 * Copyright (c) 2012 Ken Zhang (cpp.china@gmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 *
 */


#include <stdio.h>
#include <string.h>
#include <ctype.h>

int dump(char *buffer, size_t size, const unsigned char *mem, size_t count)
{
	const int N_EACH_LINE = 0x10;
	size_t i = 0, j, n, pos = 0;

	if (size == 0) {
		return 0;
	}
	else {
		buffer[0] = '\0';
	}

	while (i < count) {
		/* calculate number of bytes to dump for this line */
		n = (count - i) > N_EACH_LINE ? N_EACH_LINE : (count - i);
		if (size - pos < 4 * N_EACH_LINE + 15) {
			break;
		}

		/* print address */
		pos += sprintf(buffer + pos, "%08X  ", (i / N_EACH_LINE) * N_EACH_LINE);

		/* print content in hex */
		for (j = 0; j < N_EACH_LINE; j++) {
			if (j == N_EACH_LINE / 2) {
				pos += sprintf(buffer + pos, n > j ? "- " : "  ");
			}

			if (j < n) {
				pos += sprintf(buffer + pos, "%02X ", mem[i + j]);
			}
			else {
				pos += sprintf(buffer + pos, "   ");
			}
		}

		/* print content in ascii */
		pos += sprintf(buffer + pos, " ");
		for (j = 0; j < N_EACH_LINE; j++) {
			if (j < n) {
				buffer[pos++] = isprint(mem[i + j]) ? mem[i + j] : '.';
			}
			else {
				buffer[pos++] = ' ';
			}
		}

		/* new line */
		pos += sprintf(buffer + pos, "\n");
		i += n;;
	}

	return pos;
}

int main()
{
	char buffer[2000];
	unsigned char bytes[256];
	int i;

	for (i = 0; i < sizeof(bytes); i++) {
		bytes[i] = (unsigned char)i;
	}

	dump(buffer, sizeof(buffer), bytes, sizeof(bytes));
	puts(buffer);
}

